// 1 push方法
// 该方法接受任意个参数 然后添加到数组的末尾
// function push (arr, ...arg) {
//   // console.log(arg)
//   // let len = arr.length
//   for (let i = 0; i < arg.length; i++) {
//     // arr.length = len + i
//     // arr[arr.length] = arg[i]
//     arr[arr.length++] = arg[i] // 或者直接在for中这样写
//   }
//   return arr.length
// }

// let arr = [1, 2, 3, 4]
// push(arr, 1, 2)
// console.log(arr)
// console.log(arr.length)

// 2 pop方法
// 该方法删除并返回数组的最后一个元素 如果数组为空 返回undefined
// function pop (arr) {
//   if (arr.length === 0) {
//     console.log('数组为空')
//     return
//   }
//   let tmp = arr[arr.length - 1]
//   arr.length--
//   return tmp
// }
// let arr = [1, 2, 3, 4]
// console.log(pop(arr))
// console.log(arr)

// 3 shift方法
// 该方法删除并返回数组的第一个元素 实现时我们只要将第二个元素的值付给第一个 第三个的值赋给第二个 以此类推 直到最后一个
// function shift (arr) {
//   if (arr.length === 0) {
//     console.log('数组为空')
//     return
//   }
//   let tmp = arr[0]
//   for (let i = 0; i < arr.length; i++) {
//     arr[i] = arr[i + 1]
//   }
//   arr.length--
//   return tmp
// }
// let arr = [2, 4, 6, 8]
// console.log(shift(arr))
// console.log(arr)

// 4 unshift方法
// 该方法将任意个数插入到数组的前面 实现方法 将数组从最后一个元素开始依次向后移动参数的个数个位置 即把前面的位置空出来 然后再把参数依次插入到前面
// function unshift (arr, ...arg) {
//   let len = arg.length
//   for (let j = arr.length - 1; j >= 0; j--) {
//     arr[j + len] = arr[j]
//   }
//   for (let i = 0; i < len; i++) {
//     arr[i] = arg[i]
//   }
//   return arr.length
// }
// let arr = [2, 4, 6, 8]
// console.log(unshift(arr, 1, 2))
// console.log(arr)

// 5 concat方法
// 该方法接受将任意多个参数合并到原数组后 值得注意的是 如果参数是一个数组 需要将数组展开
// function concat (arr, ...arg) {
//   let newArr = []
//   let i = 0
//   for (; i < arr.length; i++) {
//     newArr[i] = arr[i]
//   }
//   for (let j = 0; j < arg.length; j++) {
//     if (arg[j].push) { // 判断是不是数组
//       for (let k = 0; k < arg[j].length; k++) {
//         newArr[i++] = arg[j][k]
//       }
//     } else {
//       newArr[i++] = arg[j]
//     }
//   }
//   return newArr
// }
// let arr = [2, 4, 6, 8]
// console.log(concat(arr, [1], 2))

// 6 slice方法
// 该方法接受两个参数 第一个参数是截取区间的开始索引 第二个参数是结束索引+1 需要注意的是
// - 原生的slice方法当传入的第一个参数不是非数字类型 默认为0 参数为负数则加上数组的长度计算 如果负数的绝对值大于数组的长度 则算作0
// - 第二个参数不是数值时默认为数组长度 如果为负数则加上数组的长度计算 如果负数的绝对值大于数组长度 则算作0
// - 返回值截取的数组
// function slice(arr, start, end) {
//   start = typeof start === 'number' ? start : 0 //判断输入是否为数字 不为数字则代表0
//   start = start < 0 ? start + arr.length : start // 如果小于0 则加上数组长度
//   start = start < 0 ? 0 : start // 如果还小于0 代表超过边界 所以算作边界
//   end = typeof end === 'number' ? end : arr.length
//   end = end < 0 ? end + arr.length : end
//   end = end < 0 ? 0 : end
//   let newArr = []
//   let j = 0
//   for (let i = start; i < end && i < arr.length; i++) {
//     newArr[j++] = arr[i]
//   }
//   return newArr
// }
// let arr = [2, 4, 6, 8]
// console.log(slice(arr, 3, 4))

// 7 splice方法
// 该方法接受多个参数 其中第一个参数为开始删除的位置 第二个参数为删除的长度 后面的参数为在删除位置替换的元素 值得注意的是
// - 当第二个参数为0时 该函数可以用于在数组中插入元素
// - 原生的splice方法当传入的第一个参数是非数字类型 默认为0 参数为负数则加上数组的长度计算 如果负数的绝对值大于数组的长度 则算作0
// - 第二个参数如果为非数值或者负数 都算作0
// function splice (arr, start, num, ...arg) {
//   start = typeof start === 'number' ? start : 0
//   start = start < 0 ? start + arr.length : start
//   start = start < 0 ? 0 : start
//   num = (typeof num !== 'number' || num < 0) ? 0 : num
//   let len = arg.length
//   let newArr = []
//   for (let k = 0; k < num; k++) {
//     newArr[k] = arr[k + start]
//   }
//   let arrlen = arr.length
//   for (let i = start; i < arrlen - num; i++) { // 删除节点
//     arr[i] = arr[i + num]
//   }
//   arr.length -= num
//   arrlen = arr.length
//   for (let j = arrlen - 1; j > arrlen - 1 - len; j--) { // 空出替换位置
//     arr[j + len] = arr[j]
//   }
//   for (let j = start; j < start + len; j++) {
//     arr[j] = arg[j - start]
//   }
//   return newArr
// }
// let arr = [2, 4, 6, 8]
// console.log(splice(arr, 1, 2, 1))
// console.log(arr)

// 8 reverse方法
// 该方法用于倒置数组 我们将数组第一个数和最后一个交换 第二个数和倒数第二个交换 以此类推 值得注意的是 该方法不仅会改变原数组 还会返回原数组
// function reverse (arr) {
//   for (let i = 0; i < arr.length / 2; i++) {
//     let tmp = arr[i]
//     arr[i] = arr[arr.length - 1 -i]
//     arr[arr.length - 1 -i] = tmp
//   }
//   return arr
// }
// let arr = [2, 4, 6, 8]
// console.log(reverse(arr))
// 9 indexOf方法
// 该方法接受一个数据 返回该数据在数组中的从左往右第一个索引
// function indexOf (arr,value) {
//   for (let i = 0; i < arr.length; i++) {
//     if (arr[i] === value) {
//       return i
//     }
//   }
//   return -1
// }
// let arr = [2, 4, 6, 8]
// console.log(indexOf(arr, 1))
// console.log(indexOf(arr, 6))

// 10 lastIndexOf方法
// 该方法接受一个数据 返回该数据在数组中的从右往左第一个索引
// function lastIndexOf (arr, value) {
//   for (let i = arr.length - 1; i > 0; i--) {
//     if (arr[i] === value) {
//       return i
//     }
//   }
//   return -1
// }
// let arr = [2, 4, 6, 8]
// console.log(lastIndexOf(arr, 1))
// console.log(lastIndexOf(arr, 6))

// 改变原数组：﻿
// pop():   删除 arrayObject 的最后一个元素，把数组长度减 1，并且返回它删除的元素的值。如果数组已经为空，则 pop() 不 改变数组，并返回 undefined 值。arrayObject.pop() 

 

// push():push() 方法可把它的参数顺序添加到 arrayObject 的尾部。它直接修改 arrayObject，而不是创建一个新的数组，arrayObject.push(newelement1,newelement2,….,newelementX) 


// reverse():该方法会改变原来的数组----将原来的数组倒序，而不会创建新的数组。arrayObject.reverse() 


// shift():   删除数组的第一个元素，并返回第一个元素的值,如果数组是空的，那么 shift() 方法将不进行任何操作. 

 

// unshift():  unshift() 方法可向数组的开头添加一个或更多元素，并返回新的长度。arrayObject.unshift(newelement1,newelement2,….,newelementX)返回arrayObject 的新长度


// sort():   对数组的引用。请注意，数组在原数组上进行排序，不生成副本。arrayObject.sort(sortby) (如果调用该方法时没有使用参数，将按字母顺序对数组中的元素进行排序，说得更精确点，是按照字符编码的顺序进行排序。要实现这一点，首先应把数组的元素都转换成字符串（如有必要），以便进行比较。 
// 如果想按照其他标准进行排序，就需要提供比较函数，该函数要比较两个值，然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b，其返回值如下： 
// 若 a 小于 b，在排序后的数组中 a 应该出现在 b 之前，则返回一个小于 0 的值。 
// 若 a 等于 b，则返回 0。 
// 若 a 大于 b，则返回一个大于 0 的值。) 


// splice():  splice() 方法可删除从 index 处开始的零个或多个元素，并且用参数列表中声明的一个或多个值来替换那些被删除的元素。 如果从 arrayObject 中删除了元素，则返回的是含有被删除的元素的数组 arrayObject.splice(index,howmany,item1,…..,itemX) 
 

 

// 不改变原数组：
// concat()：用于连接两个或多个数组，仅会返回被连接数组的一个副本，arrayObject.concat(arrayX,arrayX,……,arrayX) 


// join()：返回一个字符串。该字符串是通过把 arrayObject 的每个元素转换为字符串，然后把这些字符串连接起来,arrayObject.join(separator) 


// slice()：arrayObject.slice(start,end)返回一个新的数组，包含从 start 到 end （不包括该元素）的 arrayObject 中的元素。